﻿using Analyse.DrawingPerformance.Model;
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Drawing;

namespace Analyse.DrawingPerformance.Contract
{
    public class SkiaSharpDrawingEngine : IDrawingEngine
    {
        public byte[] Draw(int width, int height, List<BaseDrawElement> drawElements)
        {
            var functions = new Dictionary<Type, Func<SKSurface, BaseDrawElement, bool>>();
            functions.Add(typeof(ImageDrawElement), DrawImage);
            functions.Add(typeof(TextDrawElement), DrawText);

            var info = new SKImageInfo(width, height);
            using (var surface = SKSurface.Create(info))
            {
                surface.Canvas.Clear(SKColor.Parse("#ffffff"));

                if (drawElements != null)
                {
                    foreach (var drawElement in drawElements)
                    {
                        functions.TryGetValue(drawElement.GetType(), out var function);
                        function?.Invoke(surface, drawElement);
                    }
                }

                using (var image = surface.Snapshot())
                using (var data = image.Encode(SKEncodedImageFormat.Png, 100))
                {
                    return data.ToArray();
                }
            }
        }

        private bool DrawImage(SKSurface surface, BaseDrawElement drawElement)
        {
            var item = drawElement as ImageDrawElement;
            using (var paint = new SKPaint())
            {
                using (var bitmap = SKBitmap.Decode(item.ImagePath))
                {
                    surface.Canvas.DrawBitmap(bitmap, item.X, item.Y, paint);
                }
            }

            return true;
        }

        private bool DrawText(SKSurface surface, BaseDrawElement drawElement)
        {
            var item = drawElement as TextDrawElement;
            var color = ColorTranslator.FromHtml(item.Color);

            using (var paint = new SKPaint())
            {
                paint.TextSize = item.Size;
                paint.IsAntialias = true;
                paint.Color = new SKColor(color.R, color.G, color.B);
                paint.IsStroke = false;
                if (!string.IsNullOrEmpty(item.FontPath))
                {
                    paint.Typeface = SKTypeface.FromFile(item.FontPath);
                }

                surface.Canvas.DrawText(item.Text, item.X, item.Y, paint);
            }

            return true;
        }
    }
}
